Array Indexing
csdl
supports indexing into Variable
objects for explicit
outputs.
In this example, integer indices are used to concatenate multiple expressions/variables into one variable and extract values from a single variable representing an array.
The variable representing the array, 'x'
, is created with the
Model.create_output
method.
Array index assignments are then used to define 'x'
in terms of
other CSDL variables.
Note: For every variable created with Model.create_output
, there is no
need to call Model.register_output
.
from csdl_om import Simulatorimport numpy as npimport csdlfrom csdl import Model
class ExampleInteger(Model):
def define(self): a = self.declare_variable('a', val=0) b = self.declare_variable('b', val=1) c = self.declare_variable('c', val=2) d = self.declare_variable('d', val=7.4) e = self.declare_variable('e', val=np.pi) f = self.declare_variable('f', val=9) g = e + f x = self.create_output('x', shape=(7, )) x[0] = a x[1] = b x[2] = c x[3] = d x[4] = e x[5] = f x[6] = g
# Get value from indices self.register_output('x0', x[0]) self.register_output('x6', x[6]) self.register_output('x_2', x[-2])
sim = Simulator(ExampleInteger())sim.run()
print('x', sim['x'].shape)print(sim['x'])print('x0', sim['x0'].shape)print(sim['x0'])print('x6', sim['x6'].shape)print(sim['x6'])
[ 0. 1. 2. 7.4 3.14159265 9. 12.14159265]x0 (1,)[0.]x6 (1,)[12.14159265]
csdl
supports specifying ranges as well as individual indices to
slice and concatenate arrays.
from csdl_om import Simulatorimport numpy as npimport csdlfrom csdl import Model
class ExampleOneDimensional(Model):
def define(self): n = 20 u = self.declare_variable('u', shape=(n, ), val=np.arange(n).reshape((n, ))) v = self.declare_variable('v', shape=(n - 4, ), val=np.arange(n - 4).reshape( (n - 4, ))) w = self.declare_variable('w', shape=(4, ), val=16 + np.arange(4).reshape((4, ))) x = self.create_output('x', shape=(n, )) x[0:n] = 2 * (u + 1) y = self.create_output('y', shape=(n, )) y[0:n - 4] = 2 * (v + 1) y[n - 4:n] = w - 3
# Get value from indices z = self.create_output('z', shape=(3, )) z[0:3] = csdl.expand(x[2], (3, )) self.register_output('x0_5', x[0:5]) self.register_output('x3_', x[3:]) self.register_output('x2_4', x[2:4]) self.register_output('x_last', x[-1])
sim = Simulator(ExampleOneDimensional())sim.run()
print('x', sim['x'].shape)print(sim['x'])print('y', sim['y'].shape)print(sim['y'])print('z', sim['z'].shape)print(sim['z'])print('x0_5', sim['x0_5'].shape)print(sim['x0_5'])print('x3_', sim['x3_'].shape)print(sim['x3_'])print('x2_4', sim['x2_4'].shape)print(sim['x2_4'])
[ 2. 4. 6. 8. 10. 12. 14. 16. 18. 20. 22. 24. 26. 28. 30. 32. 34. 36. 38. 40.]y (20,)[ 2. 4. 6. 8. 10. 12. 14. 16. 18. 20. 22. 24. 26. 28. 30. 32. 13. 14. 15. 16.]z (3,)[6. 6. 6.]x0_5 (5,)[ 2. 4. 6. 8. 10.]x3_ (17,)[ 8. 10. 12. 14. 16. 18. 20. 22. 24. 26. 28. 30. 32. 34. 36. 38. 40.]x2_4 (2,)[6. 8.]
csdl
supports specifying ranges along multiple axes as well as
individual indices and ranges to slice and concatenate arrays.
from csdl_om import Simulatorimport numpy as npimport csdlfrom csdl import Model
class ExampleMultidimensional(Model):
def define(self): # Works with two dimensional arrays z = self.declare_variable('z', shape=(2, 3), val=np.arange(6).reshape((2, 3))) x = self.create_output('x', shape=(2, 3)) x[0:2, 0:3] = z
# Also works with higher dimensional arrays p = self.declare_variable('p', shape=(5, 2, 3), val=np.arange(30).reshape((5, 2, 3))) q = self.create_output('q', shape=(5, 2, 3)) q[0:5, 0:2, 0:3] = p
# Get value from indices self.register_output('r', p[0, :, :]) self.register_output('r2', p[0, -1, 2])
# Assign a vector to a slice vec = self.create_input( 'vec', shape=(1, 20), val=np.arange(20).reshape((1, 20)), ) s = self.create_output('s', shape=(2, 20)) s[0, :] = vec s[1, :] = 2 * vec
# Negative indices and unassigned indices that take on default # values t = self.create_output('t', shape=(5, 3, 3), val=0) t[0:5, 0:-1, 0:3] = p
sim = Simulator(ExampleMultidimensional())sim.run()
print('x', sim['x'].shape)print(sim['x'])print('q', sim['q'].shape)print(sim['q'])print('r', sim['r'].shape)print(sim['r'])print('r2', sim['r2'].shape)print(sim['r2'])print('s', sim['s'].shape)print(sim['s'])print('t', sim['t'].shape)print(sim['t'])
[[0. 1. 2.] [3. 4. 5.]]q (5, 2, 3)[[[ 0. 1. 2.] [ 3. 4. 5.]]
[[ 6. 7. 8.] [ 9. 10. 11.]]
[[12. 13. 14.] [15. 16. 17.]]
[[18. 19. 20.] [21. 22. 23.]]
[[24. 25. 26.] [27. 28. 29.]]]r (1, 2, 3)[[[0. 1. 2.] [3. 4. 5.]]]r2 (1, 1, 1)[[[5.]]]s (2, 20)[[ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.] [ 0. 2. 4. 6. 8. 10. 12. 14. 16. 18. 20. 22. 24. 26. 28. 30. 32. 34. 36. 38.]]t (5, 3, 3)[[[ 0. 1. 2.] [ 3. 4. 5.] [ 0. 0. 0.]]
[[ 6. 7. 8.] [ 9. 10. 11.] [ 0. 0. 0.]]
[[12. 13. 14.] [15. 16. 17.] [ 0. 0. 0.]]
[[18. 19. 20.] [21. 22. 23.] [ 0. 0. 0.]]
[[24. 25. 26.] [27. 28. 29.] [ 0. 0. 0.]]]